<script setup>
import { ref, watch, computed } from 'vue'
import { ElMessage } from 'element-plus'
import logger from '@/utils/logger'
import { saveGoodsPrice } from '@/api/goodsPrice'
import { fetchDealerGoodsStoreList } from '@/api/goods'
import StoreGoodsSelector from './StoreGoodsSelector.vue'
import { useUserStore } from '@/stores/user'
import { formatDateTime, getNowDateTime } from '@/utils/dayjs'
import { generatePriceOrderNo } from '@/utils/generateOrderNo'

const emit = defineEmits(['success', 'close'])

const props = defineProps({
  isPreview: { type: Boolean, default: false },
  hideFooter: { type: Boolean, default: false },
})

// 使用defineModel接收父组件传递的数据
const modelValue = defineModel({ type: Object, default: null })

// 获取当前用户信息
const userStore = useUserStore()
const currentUser = computed(() => userStore.nickname || '未登录')

// 控制商品选择器对话框的显示状态
const selectorVisible = ref(false)

// 创建默认表单数据的函数，避免重复定义
const createDefaultFormData = () => ({
  updatePriceMId: '',
  priceNo: generatePriceOrderNo(),
  notes: '',
  pzUpdatePriceDList: [],
  operator: currentUser.value,
  auditor: '',
  priceTime: getNowDateTime(),
  checkTime: '',
  isCheck: false,
})

// 表单数据
const formData = ref(createDefaultFormData())

// 选中的商品列表，用于与商品选择器组件交互
const selectedGoods = ref([])

/**
 * 监听选中商品的变化，自动更新表单中的商品列表
 * 如果商品已存在则保留原有信息，否则创建新的商品项
 */
watch(selectedGoods, (newVal) => {
  const existingMap = new Map(
    formData.value.pzUpdatePriceDList.map((item) => [item.dealerGoodsStoreId, item]),
  )

  const newList = newVal.map((good) => {
    const cached = existingMap.get(good.dealerGoodsStoreId)
    if (cached) return cached
    return {
      dealerGoodsStoreId: good.dealerGoodsStoreId,
      dealerGoodsName: good.goodsName || '',
      goodsPicture: good.goodsPicture || '',
      periodStartingDate: good.periodStartingDate,
      periodEndDate: good.periodEndDate,
      points: good.points,
      pointsNew: good.unitPrice,
    }
  })
  formData.value.pzUpdatePriceDList = newList
})

// 表单验证规则
const rules = {
  priceNo: [
    { required: true, message: '请输入调价单号', trigger: 'blur' },
    { min: 1, message: '调价单号不能为空', trigger: 'change' },
  ],
  pzUpdatePriceDList: [
    { required: true, type: 'array', min: 1, message: '至少添加一种商品', trigger: 'change' },
  ],
}

// 表单引用，用于手动触发验证
const formRef = ref(null)

/**
 * 初始化表单数据
 * 如果有传入的modelValue则用其初始化表单，否则使用默认初始值
 */
const initFormData = () => {
  if (!modelValue.value) {
    formData.value = createDefaultFormData()
    selectedGoods.value = []
    return
  }

  const {
    updatePriceMId = '',
    priceNo = '',
    notes = '',
    pzUpdatePriceDList = [],
    operatorName = currentUser.value,
    checkerName = '',
    isCheck = false,
    priceTime = getNowDateTime(),
    checkTime = '',
  } = JSON.parse(JSON.stringify(modelValue.value))

  formData.value = {
    updatePriceMId,
    priceNo,
    notes,
    pzUpdatePriceDList: pzUpdatePriceDList.map((item) => ({
      ...item,
      points: item.points,
      pointsNew: item.pointsNew,
    })),
    operator: operatorName,
    auditor: checkerName,
    priceTime,
    checkTime,
    isCheck,
  }

  selectedGoods.value = pzUpdatePriceDList
  fetchStoreGoodsDetails()
}

/**
 * 获取商品库存详情信息
 * 用于补充商品列表中可能缺失的详细信息
 */
const fetchStoreGoodsDetails = async () => {
  const goodsList = formData.value.pzUpdatePriceDList
  if (!goodsList?.length) return

  try {
    const res = await fetchDealerGoodsStoreList({ currentPage: 1, pageSize: 9999, queryFields: {} })
    if (res.success && res.data?.list?.length) {
      const goodsStoreMap = new Map(res.data.list.map((item) => [item.dealerGoodsStoreId, item]))
      goodsList.forEach((item) => {
        const storeItem = goodsStoreMap.get(item.dealerGoodsStoreId)
        if (storeItem) {
          Object.assign(item, {
            dealerGoodsName: storeItem.goodsName,
            goodsPicture: storeItem.goodsPicture,
            periodStartingDate: storeItem.periodStartingDate,
            periodEndDate: storeItem.periodEndDate,
          })
        }
      })
    }
  } catch (error) {
    logger.error('获取库存商品详情失败', error)
  }
}

/**
 * 打开商品选择器对话框
 */
const openGoodsSelector = () => {
  selectorVisible.value = true
}

/**
 * 关闭商品选择器对话框
 */
const closeSelector = () => {
  selectorVisible.value = false
}

/**
 * 从表单中移除指定索引的商品
 * @param {number} index - 要移除的商品在列表中的索引
 */
const removeGoods = (index) => {
  const goodsToRemove = formData.value.pzUpdatePriceDList[index]
  formData.value.pzUpdatePriceDList.splice(index, 1)
  selectedGoods.value = selectedGoods.value.filter(
    (item) => item.dealerGoodsStoreId !== goodsToRemove.dealerGoodsStoreId,
  )
}

/**
 * 验证表单数据
 * @returns {Promise<boolean>} 验证结果
 */
const validateForm = async () => {
  // 检查单号是否为空
  if (!formData.value.priceNo?.trim()) {
    ElMessage.error('调价单号不能为空')
    return false
  }

  // 检查是否添加了商品
  if (!formData.value.pzUpdatePriceDList?.length) {
    ElMessage.error('请至少添加一种商品')
    return false
  }

  try {
    // 使用表单验证
    const valid = await formRef.value?.validate().catch(() => false)
    if (!valid) {
      ElMessage.error('请填写必填项')
      return false
    }

    // 验证价格字段
    for (const item of formData.value.pzUpdatePriceDList) {
      if (item.pointsNew === null || item.pointsNew < 0) {
        ElMessage.warning(`商品 ${item.dealerGoodsName} 的新价格不能是负数`)
        return false
      }
      if (!Number.isInteger(Number(item.pointsNew))) {
        ElMessage.warning(`商品 ${item.dealerGoodsName} 的新价格仅支持整数`)
        return false
      }
    }

    return true
  } catch (error) {
    logger.error('表单验证失败', error)
    ElMessage.error('表单验证失败')
    return false
  }
}

/**
 * 提交表单数据
 * @param {number} editType - 编辑类型：0=新增，1=修改，2=保存并审核
 */
const submitForm = async (editType) => {
  if (!(await validateForm())) return

  try {
    // 准备提交数据
    const submitData = {
      ...formData.value,
      isCheck: editType === 2,
      priceTime: formatDateTime(formData.value.priceTime, 'YYYY-MM-DD HH:mm:ss'),
      checkTime:
        editType === 2
          ? getNowDateTime()
          : formData.value.checkTime
            ? formatDateTime(formData.value.checkTime, 'YYYY-MM-DD HH:mm')
            : null,
      editType,
      pzUpdatePriceDList: formData.value.pzUpdatePriceDList.map(
        ({ dealerGoodsStoreId, points, pointsNew, updatePriceDId }) => ({
          dealerGoodsStoreId,
          points,
          pointsNew,
          updatePriceDId: updatePriceDId || null,
        }),
      ),
    }

    const res = await saveGoodsPrice(submitData)
    if (res.success) {
      ElMessage.success('保存成功')
      emit('success')
      emit('close')
    } else {
      ElMessage.error(res.msg || '保存失败')
    }
  } catch (error) {
    logger.error('保存调价单失败', error)
    ElMessage.error('保存调价单失败')
  }
}

/**
 * 取消提交并关闭表单
 */
const cancelSubmit = () => {
  emit('close')
}

// 组件初始化时执行初始化表单数据
initFormData()
</script>

<template>
  <el-dialog
    v-model="selectorVisible"
    title="勾选需要调价的商品"
    width="80%"
    append-to-body
    align-center
    destroy-on-close
  >
    <StoreGoodsSelector
      v-model:selectedGoods="selectedGoods"
      @close="closeSelector"
      @confirm="closeSelector"
    />
  </el-dialog>

  <div class="price-container">
    <div class="receipt-header">
      <div class="receipt-title">调价单</div>
      <div class="receipt-no">
        <span class="label">NO:</span>
        <el-input
          v-model="formData.priceNo"
          placeholder="单号已自动生成，可修改"
          class="no-input"
          :disabled="props.isPreview"
        />
      </div>
    </div>
    <el-form ref="formRef" :model="formData" :rules="rules" label-width="auto" class="price-form">
      <div class="form-row">
        <el-form-item label="操作人员">
          <el-input v-model="formData.operator" disabled />
        </el-form-item>
        <el-form-item label="调价时间">
          <el-input :value="formatDateTime(formData.priceTime, 'YYYY-MM-DD HH:mm:ss')" disabled />
        </el-form-item>
      </div>
      <div class="form-row">
        <el-form-item label="审核人">
          <el-input v-model="formData.auditor" disabled placeholder="审核后自动填写" />
        </el-form-item>
        <el-form-item label="审核时间">
          <el-input
            :value="formatDateTime(formData.checkTime, 'YYYY-MM-DD HH:mm')"
            disabled
            placeholder="审核后自动填写"
          />
        </el-form-item>
      </div>
      <div class="form-row">
        <el-form-item label="备注">
          <el-input
            v-model="formData.notes"
            type="textarea"
            :rows="1"
            resize="none"
            placeholder="请输入备注"
            :disabled="props.isPreview"
          />
        </el-form-item>
      </div>
    </el-form>
    <div class="goods-section">
      <div class="section-header">
        <h3>商品明细</h3>
        <div class="price-reminder">价格仅支持整数，不可输入小数</div>
        <el-button v-if="!props.isPreview" type="primary" size="small" @click="openGoodsSelector">
          <template #icon>
            <el-icon><LineMdPlus /></el-icon>
          </template>
          添加商品
        </el-button>
      </div>
      <el-table
        :data="formData.pzUpdatePriceDList"
        style="width: 100%"
        class="goods-table"
        :empty-text="'请选择需要调价的库存商品'"
      >
        <el-table-column label="序号" type="index" width="60" align="center" />
        <el-table-column label="商品图片" width="80" align="center">
          <template #default="{ row }">
            <el-image
              v-if="row.goodsPicture"
              :src="row.goodsPicture"
              style="width: 40px; height: 40px; border-radius: 4px"
              :preview-src-list="[row.goodsPicture]"
              fit="cover"
              preview-teleported
            />
            <div v-else class="no-image">无图片</div>
          </template>
        </el-table-column>
        <el-table-column prop="dealerGoodsName" label="商品名称" min-width="150" align="center" />
        <el-table-column label="有效期" min-width="200" align="center">
          <template #default="{ row }">
            {{ formatDateTime(row.periodStartingDate, 'YYYY-MM-DD') }} 至
            {{ formatDateTime(row.periodEndDate, 'YYYY-MM-DD') }}
          </template>
        </el-table-column>
        <el-table-column prop="points" label="原价格（元）" width="120" align="center" />
        <el-table-column label="新价格（元）" width="200" align="center">
          <template #default="{ row }">
            <el-input-number
              v-model="row.pointsNew"
              :min="0"
              :precision="0"
              :step="1"
              :disabled="props.isPreview"
              style="width: 100%"
            />
          </template>
        </el-table-column>
        <el-table-column v-if="!props.isPreview" label="操作" width="100" align="center">
          <template #default="{ $index }">
            <el-button type="danger" size="small" circle @click="removeGoods($index)">
              <template #icon>
                <el-icon><LineMdTrash /></el-icon>
              </template>
            </el-button>
          </template>
        </el-table-column>
      </el-table>
    </div>
    <div v-if="!props.hideFooter" class="footer-actions">
      <template v-if="!props.isPreview">
        <el-button @click="cancelSubmit">
          <template #icon>
            <el-icon><LineMdClose /></el-icon>
          </template>
          取消
        </el-button>
        <el-button type="primary" @click="submitForm(modelValue ? 1 : 0)">
          <template #icon>
            <el-icon><LineMdPlus /></el-icon>
          </template>
          保存
        </el-button>
        <el-button type="success" @click="submitForm(2)">
          <template #icon>
            <el-icon><LineMdCheckAll /></el-icon>
          </template>
          保存并审核
        </el-button>
      </template>
      <template v-else>
        <el-button @click="cancelSubmit">
          <template #icon>
            <el-icon><LineMdClose /></el-icon>
          </template>
          关闭
        </el-button>
      </template>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.price-container {
  height: calc(100vh - 200px);
  display: flex;
  flex-direction: column;
  gap: 20px;
  overflow: hidden;
}
.receipt-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  position: relative;
  flex: 0 0 auto;
  &::before {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: -10px;
    height: 1px;
    border-radius: 10px;
    background-color: #cbcbcb;
  }
  .receipt-title {
    font-size: 28px;
    font-weight: bold;
    color: #303133;
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
  }

  .receipt-no {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-left: auto;

    .label {
      font-weight: bold;
      font-size: 16px;
    }

    .no-input {
      width: 200px;
    }
  }
}
.price-form {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  gap: 15px;
}

.form-row {
  display: flex;
  gap: 20px;

  :deep(.el-form-item) {
    flex: 1;
    margin-bottom: 0;
  }
}
.goods-section {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 15px;
  overflow: auto;

  .section-header {
    display: flex;
    justify-content: space-between;
    align-items: center;

    h3 {
      margin: 0;
      font-size: 16px;
      font-weight: bold;
    }
  }
}
.goods-table {
  border: 1px solid #ebeef5;
  border-radius: 4px;
  .no-image {
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    color: #909399;
    background-color: #f5f7fa;
    font-size: 12px;
    border-radius: 4px;
    border: 1px dashed #d9d9d9;
    margin: 0 auto;
  }
}
.footer-actions {
  flex: 0 0 auto;
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}
.price-reminder {
  color: #e6a23c;
  font-size: 12px;
}
</style>
